package com.todo.content.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.api.client.util.Lists;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.enums.EnableTypeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.common.utils.StringUtils;
import com.todo.component.redis.RedisService;
import com.todo.content.application.convert.ContentConvert;
import com.todo.content.application.entity.bo.ContentClassifyBO;
import com.todo.content.application.entity.condition.ContentClassifyConditionBO;
import com.todo.content.application.service.ContentClassifyService;
import com.todo.content.common.base.ContentKeyBuild;
import com.todo.content.infrastructure.entity.condition.ContentClassifyCondition;
import com.todo.content.infrastructure.entity.po.ContentClassifyPO;
import com.todo.content.infrastructure.repository.ContentClassifyRepository;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * (ContentClassify)表服务实现类
 *
 * @author zhangwenxiang
 * @since 2024-03-04 00:19:45
 */
@Slf4j
@Service("contentClassifyService")
public class ContentClassifyServiceImpl implements ContentClassifyService {

    public static final int MAX_QUERY_SIZE = 100;

    @Resource
    private ContentClassifyRepository contentClassifyRepository;
    @Resource
    private RedisService redisService;

    @Override
    public Boolean insertContentClassify(ContentClassifyBO contentClassifyBO) {
        if (contentClassifyBO == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        ContentClassifyBO alreadyContentClassifyBO = queryContentClassifyByCode(contentClassifyBO.getCode());
        if (alreadyContentClassifyBO != null) {
            log.warn("ContentClassifyService#insertContentClassify 新增分类信息失败，话题code已存在 contentClassifyBO：【{}】", JSONObject.toJSONString(contentClassifyBO));
            return false;
        }
        ContentClassifyPO alreadyContentClassifyPO = contentClassifyRepository.queryContentClassifyPOByName(contentClassifyBO.getName());
        if (alreadyContentClassifyPO != null) {
            log.warn("ContentClassifyService#insertContentClassify 新增分类信息失败，话题名称已存在 contentClassifyBO：【{}】", JSONObject.toJSONString(contentClassifyBO));
            return false;
        }
        ContentClassifyPO contentClassifyPO = ContentConvert.convertToContentClassifyPO(contentClassifyBO);
        Boolean inserted = contentClassifyRepository.insertContentClassifyPO(contentClassifyPO);
        if (inserted) {
            String classifySetKey = ContentKeyBuild.buildContentClassifySetKey();
            redisService.hSet(classifySetKey, contentClassifyBO.getCode(), JSONObject.toJSONString(contentClassifyBO));
        }
        return inserted;
    }

    @Override
    public Boolean updateContentClassifyById(ContentClassifyBO contentClassifyBO) {
        if (contentClassifyBO == null || contentClassifyBO.getClassifyId() == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        ContentClassifyBO alreadyContentClassifyBO = queryContentClassifyById(contentClassifyBO.getClassifyId());
        if (!EnableTypeEnum.FORBIDDEN.equals(alreadyContentClassifyBO.getIsEnable())) {
            log.warn("ContentClassifyService#updateContentClassifyById 更新内容分类失败，当前分类信息不为禁止状态，禁止操作 contentClassifyBO：【{}】", JSONObject.toJSONString(contentClassifyBO));
            return false;
        }
        if (!alreadyContentClassifyBO.getCode().equals(contentClassifyBO.getCode())) {
            log.warn("ContentClassifyService#updateContentClassifyById 更新内容分类失败,分类code不允许调整 contentClassifyBO：【{}】", JSONObject.toJSONString(contentClassifyBO));
            return false;
        }
        if (!alreadyContentClassifyBO.getName().equals(contentClassifyBO.getName())) {
            ContentClassifyPO alreadyContentClassifyPO = contentClassifyRepository.queryContentClassifyPOByName(contentClassifyBO.getName());
            if (alreadyContentClassifyPO != null) {
                log.warn("ContentClassifyService#updateContentClassifyById 更新分类信息失败，话题名称已存在 contentClassifyBO：【{}】", JSONObject.toJSONString(contentClassifyBO));
                return false;
            }
        }
        ContentClassifyPO contentClassifyPO = ContentConvert.convertToContentClassifyPO(contentClassifyBO);
        Boolean updated = contentClassifyRepository.updateContentClassifyPOById(contentClassifyPO);
        if (updated){
            String classifySetKey = ContentKeyBuild.buildContentClassifySetKey();
            redisService.hSet(classifySetKey, contentClassifyBO.getCode(), JSONObject.toJSONString(contentClassifyBO));
        }
        return updated;
    }

    @Override
    public Boolean removeContentClassifyById(Long classifyId) {
        if (classifyId == null || classifyId < 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        ContentClassifyBO contentClassifyBO = queryContentClassifyById(classifyId);
        if (contentClassifyBO == null) {
            return true;
        }
        Boolean removed = contentClassifyRepository.removeContentClassifyPOById(classifyId);
        if (removed){
            String classifySetKey = ContentKeyBuild.buildContentClassifySetKey();
            redisService.hDel(classifySetKey, contentClassifyBO.getCode());
        }
        return removed;
    }

    @Override
    public ContentClassifyBO queryContentClassifyById(Long classifyId) {
        if (classifyId == null || classifyId < 0) {
            return null;
        }
        ContentClassifyPO contentClassifyPO = contentClassifyRepository.queryContentClassifyPOById(classifyId);
        ContentClassifyBO contentClassifyBO = ContentConvert.convertToContentClassifyBO(contentClassifyPO);
        return contentClassifyBO;
    }

    @Override
    public Boolean enableContentClassifyById(Long classifyId, EnableTypeEnum enableTypeEnum) {
        if (classifyId == null || classifyId < 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        ContentClassifyBO contentClassifyBO = queryContentClassifyById(classifyId);
        if (contentClassifyBO == null) {
            log.error("ContentClassifyService#enableContentClassifyById 启禁用分类信息失败，当前数据不存在 classifyId：【{}】", classifyId);
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        if (contentClassifyBO.getIsEnable().equals(enableTypeEnum)) {
            return true;
        }
        Boolean updated = contentClassifyRepository.enableContentClassifyById(classifyId, enableTypeEnum.getType());
        if (updated){
            contentClassifyBO.setIsEnable(enableTypeEnum);
            String classifySetKey = ContentKeyBuild.buildContentClassifySetKey();
            redisService.hSet(classifySetKey, contentClassifyBO.getCode(), JSONObject.toJSONString(contentClassifyBO));
        }
        return updated;
    }

    @Override
    public ContentClassifyBO queryContentClassifyByCode(String classifyCode) {
        if (StringUtils.isBlank(classifyCode)) {
            return null;
        }
        String setKey = ContentKeyBuild.buildContentClassifySetKey();
        if (redisService.hasKey(setKey)) {
            String classifyJson = redisService.hGet(ContentKeyBuild.buildContentClassifySetKey(), classifyCode);
            return JSONObject.parseObject(classifyJson, ContentClassifyBO.class);
        }
        ContentClassifyPO contentClassifyPO = contentClassifyRepository.queryContentClassifyPOByCode(classifyCode);
        ContentClassifyBO contentClassifyBO = ContentConvert.convertToContentClassifyBO(contentClassifyPO);
        if (contentClassifyBO != null) {
            redisService.hSet(setKey, contentClassifyBO.getCode(), JSONObject.toJSONString(contentClassifyBO));
        }
        return contentClassifyBO;
    }

    @Override
    public PageResult<ContentClassifyBO> queryContentClassifyByPage(ContentClassifyConditionBO conditionBO) {
        if (conditionBO == null) {
            return new PageResult<>();
        }
        ContentClassifyCondition classifyCondition = ContentConvert.convertToContentClassifyCondition(conditionBO);
        PageResult<ContentClassifyPO> pageResult = contentClassifyRepository.queryContentClassifyByCondition(classifyCondition);
        if (pageResult == null) {
            return PageResult.of(Lists.newArrayList(), conditionBO.getPageIndex(), conditionBO.getPageSize(), 0L);
        }
        PageResult<ContentClassifyBO> result = new PageResult<>();
        result.setPageNum(pageResult.getPageNum());
        result.setPageSize(pageResult.getPageSize());
        result.setResults(pageResult.getResults() == null ? null : pageResult.getResults().stream().map(ContentConvert::convertToContentClassifyBO).collect(Collectors.toList()));
        result.setTotal(pageResult.getTotal());
        result.setCurrentIndex(pageResult.getCurrentIndex());
        result.setHasNext(pageResult.isHasNext());
        return result;
    }

    @Override
    public List<ContentClassifyBO> queryContentClassifyByIdList(List<Long> classifyIdList) {
        if (CollectionUtils.isEmpty(classifyIdList)) {
            return Collections.emptyList();
        }
        if (classifyIdList.size() > MAX_QUERY_SIZE) {
            log.warn("ContentClassifyService#queryContentClassifyByIdList 参数错误，数据超限，classifyIdList：【{}】", JSONObject.toJSONString(classifyIdList));
            throw new BizException(BizErrorCodeEnum.QUANTITY_EXPLOSION);
        }
        List<ContentClassifyPO> contentClassifyPOList = contentClassifyRepository.queryContentClassifyByIdList(classifyIdList);
        return contentClassifyPOList.stream().map(ContentConvert::convertToContentClassifyBO).collect(Collectors.toList());
    }
}
